home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 501-525 / disk_509 / multi_player / sources / req_play.c < prev    next >
C/C++ Source or Header  |  1992-05-06  |  25KB  |  931 lines

  1.  
  2. /************************************************************************/
  3. /* play_c (tom_tracker!)                        */
  4. /* 21/01/90                                */
  5. /* replay de soundtracker en C, doit etre linker avec le fichier    */
  6. /* normalreplay.s                            */
  7. /* Fenetre avec pw2.5, info sur la arp.library par Commodore Revue    */
  8. /************************************************************************/
  9.  
  10.  
  11. #include <exec/types.h>
  12. #include <exec/memory.h>
  13. #include <exec/interrupts.h>
  14. #include <libraries/dos.h>
  15. #include <libraries/dosextens.h>
  16. #include <graphics/gfxbase.h>
  17. #include <hardware/custom.h>
  18. #include <hardware/intbits.h>
  19. #include "intuition/intuition.h"
  20. #include <workbench/startup.h>
  21. #include <stdio.h>
  22. #include <hardware/cia.h>
  23. #include <devices/input.h>
  24. #include "ppdata.h"
  25.  
  26. extern    struct    CIA    far ciab;
  27. extern    struct    WBStartup *WBenchMsg;
  28.  
  29. #define    OK    1
  30. #define    NOK    0
  31. #define reg register
  32. #define    FREQU_PAL    1773447/125
  33. #define FREQU_NTSC    1789773/125
  34.  
  35. int    num_musique=0;
  36.  
  37. /* Types de replay routine */
  38. typedef enum{
  39.     UNDEF,
  40.      NOISETRACKER,
  41.     STK,
  42.     JAMCRACK,
  43.     FUTURE,
  44.     STARTREKKER,
  45.     SOUNDMON,
  46.     DELTA,
  47.     SIDMON,
  48.     MARKII,
  49.     FRED,
  50.     TFMX,
  51.     PACKED,
  52.     PP
  53. }type_replay;
  54.  
  55. #include    <libraries/reqbase.h>
  56.  
  57. #ifdef    LATTICE
  58. #include    <proto/all.h>
  59. #endif
  60.  
  61. #define SIZE_INFO    2000
  62.  
  63. #define OFF_STAR        0x438
  64. #define OFF_JAM         0x0
  65. #define    OFF_STK        0x438
  66. #define    OFF_SOUND    0x1a
  67. #define    OFF_DELTA    0x51c
  68. #define OFF_PACKED    0x1f6
  69.  
  70. extern   void interrupt_music();
  71.  
  72. extern    void    pp_init(),pp_music(),pp_end();
  73. extern    void    fc_init(),fc_music(),fc_end();
  74. extern    void    st_init(),st_music(),st_end();
  75. extern    void    sm_init(),sm_music(),sm_end();
  76. extern    void    mt_init(),mt_music(),mt_end();
  77. extern    void    dlt_init(),dlt_music(),dlt_end();
  78. extern    void    sid_init(),sid_music(),sid_end();
  79. extern    void    mkii_init(),mkii_music(),mkii_end();
  80. extern    void    fred_init(),fred_music(),fred_end();
  81. extern    void    tfmx_init(),tfmx_music(),tfmx_end();
  82. extern    void    pack_init(),pack_music(),pack_end();
  83.  
  84. void    (*old_end)();
  85.  
  86. typedef    struct{
  87.     type_replay type_replay;
  88.     void    (*p_start)();
  89.     void    (*p_music)();
  90.     void    (*p_end)();
  91.     int     offset;
  92.         char    *p_ident;
  93.     char    *p_name;
  94.  
  95. }routine_replay;
  96.  
  97. /* IMPORTANT NOTE: since 0 is the end of string charactere, if you want */
  98. /* to find a pattern conataining 0, you must use the sequence: '/',0    */
  99. /* if you want to put '/', just do '/','/'                */
  100.  
  101. char    sidmon[]={'A',0xfa,0x0f,0xfa,0};
  102. char    markii[]={0x48,0xe7,'/',0,0xf0,0x41,0xfa,0x03,0x5e,0};
  103. char    fred[]=  {0x4e,0xfa,'/',0,0x4e,0x4e,0xfa,'/',0,0xcc,0};
  104.  
  105. routine_replay    tab_replay[]={
  106.  
  107.  {NOISETRACKER,    mt_init,  mt_music,  mt_end, OFF_STK,  "M.K.", "NOISETRACKER"},
  108.  {STARTREKKER,    st_init,  st_music,  st_end, OFF_STAR, "EXO4", "STARTREKKER"},
  109.  {NOISETRACKER,    st_init,  st_music,  st_end, OFF_STK,  "FLT4", "NOISTRACKE"},
  110.  {JAMCRACK,    pp_init,  pp_music,  pp_end, OFF_JAM,  "BeEp", "JAMCRACKER"},
  111.  {FUTURE,    fc_init,  fc_music,  fc_end, 0,        "FC12", "FUTURE_COMPOSER"},
  112.  {SOUNDMON,    sm_init,  sm_music,  sm_end, OFF_SOUND,"V.2",  "SOUDMON"},
  113.  {DELTA,    dlt_init, dlt_music, dlt_end,OFF_DELTA,"TA1A", "DELTA"},
  114.  {SIDMON,    sid_init, sid_music, sid_end,0,           sidmon, "SIDMON"},
  115.  {MARKII,    mkii_init,mkii_music,mkii_end,0,       markii, "MARKII"},
  116.  {MARKII,    mkii_init,mkii_music,mkii_end,0,       markii, "MARKII"},
  117.  {FRED,        fred_init,fred_music,fred_end,0,       fred,   "FRED!!!"},
  118.  {TFMX,        tfmx_init,tfmx_music,tfmx_end,0,       "TFMX", "TFMX"},
  119.  {PACKED,    pack_init,pack_music,pack_end,OFF_PACKED,"PATT","PACKED NOISETRACKER"},
  120.  {PP,        NULL,      NULL,      NULL,   0,        "PP20", "PP"},
  121.  {PP,        NULL,      NULL,      NULL,   0,        "PP11", "PP"},
  122.  {UNDEF,    NULL,      NULL,      NULL,   NULL,     NULL,   0}
  123. };
  124.  
  125.  
  126. USHORT    quit_flag = FALSE;
  127. USHORT    flag_out;
  128. int    type_replay=UNDEF;
  129. int    num_replay=0;
  130. struct  Interrupt *my_interrupt=NULL;
  131. struct    Library *myCiaPointer;
  132.  
  133. int    flg_fast=FALSE;
  134.  
  135. /* Pointeur sur les donnes soundtrack */
  136. int    *adr_data=NULL;
  137. int    *adr_data2=NULL;
  138.  
  139. int    size_file,size_read,size_file2;
  140. int    my_data;
  141.  
  142. struct Interrupt myhandler;        /* input handler */
  143. struct Interrupt handlerstuff;
  144.  
  145. void    read_file_nt();  
  146. void    read_file_tfmx();  
  147. int    setup();
  148. void    stop();
  149. void    main_loop();
  150.  
  151. char    *portname="Multi replay";
  152.  
  153. struct    MsgPort *port = NULL;
  154. struct    IOStdReq *inputreq = NULL;
  155. UBYTE    inputopen = FALSE;
  156.  
  157. struct    my_data{
  158.     struct    Task    *task;
  159.     int        sigbit;
  160. };
  161.  
  162. struct my_data    my_info;
  163. struct Window *OpenWindow();
  164. struct Window *wG;    /* we fetch the RastPort pointer from here */
  165. struct IntuitionBase *IntuitionBase=0;
  166. struct GfxBase  *GfxBase=0;
  167. struct ReqBase    *ReqBase;
  168. int        frequ=0;
  169.  
  170.  
  171. struct FileRequester    MyFileReqStruct;
  172. char fname[FCHARS];
  173. char directoryname[DSIZE];
  174. char    answerarray[DSIZE+FCHARS];
  175.  
  176. struct NewWindow IcoWindow = {
  177.     10,200,    /* window XY origin relative to TopLeft of screen */
  178.     50,30,/* window width and height */
  179.     0,1,    /* detail and block pens */
  180.     MOUSEBUTTONS+CLOSEWINDOW,/* IDCMP flags */
  181.     WINDOWDRAG+ACTIVATE+NOCAREREFRESH,    /* other window flags */
  182.     NULL,    /* first gadget in gadget list */
  183.     NULL,    /* custom CHECKMARK imagery */
  184.     "Ico",    /* window title */
  185.     NULL,    /* custom screen pointer */
  186.     NULL,    /* custom bitmap */
  187.     5,5,    /* minimum width and height */
  188.     -1,-1,    /* maximum width and height */
  189.     WBENCHSCREEN    /* destination screen type */
  190. };
  191.  
  192.  
  193. void    My_FreeMem(p_adr_data,size)
  194. char    **p_adr_data;
  195. int    size;
  196. {
  197. /*
  198.     printf("FreeMem de %lx taille:%d\n",*p_adr_data,size);
  199. */
  200.     if(*p_adr_data!=NULL){
  201.         FreeMem(*p_adr_data,size);
  202.         *p_adr_data=NULL;
  203.     }
  204. }
  205. char    *My_AllocMem(size,req,p_res)
  206. int    size;
  207. int     req;
  208. char    **p_res;
  209. {
  210.     char *p_ret;
  211.     if(*p_res!=NULL){
  212.  
  213.         printf("ERREUR!allocmem sur qq chose de deja allouer!\n");
  214.  
  215.         My_FreeMem(p_res,size);
  216.     }
  217.     p_ret=(char *)AllocMem(size,req);
  218. /*
  219.     printf("AllocMem de %lx taille:%d\n",p_ret,size);
  220. */
  221.     return(p_ret);
  222. }
  223.  
  224. /* This is for the event handler */
  225. void quit(object)
  226. APTR object;
  227. {
  228.     quit_flag = TRUE;
  229.     flag_out=TRUE;
  230. /*
  231.     stop(&my_interrupt);
  232. */
  233. }
  234. /* This is for the event handler */
  235. void new(object)
  236. APTR object;
  237. {
  238.     flag_out=TRUE;
  239. }
  240. void info();
  241. void ico();
  242.  
  243. /* This is for the event handler */
  244. void fast(object)
  245. APTR object;
  246. {
  247.     int  frequ2;
  248.     if(flg_fast==TRUE){
  249.         frequ2=frequ;
  250.         flg_fast=FALSE;
  251.     }else{
  252.         frequ2=frequ/4;
  253.         flg_fast=TRUE;
  254.     }
  255.     ciab.ciatalo=(UBYTE)(frequ2 & 0xff);
  256.     ciab.ciatahi=(UBYTE)((frequ2>>8) & 0xff);
  257. }
  258.  
  259.  
  260. /* get the PowerWindows 2.0 code */
  261. #include "window.h"
  262. #include "requ_window.h"
  263.  
  264.  
  265. /**********************************************************/
  266. /* Cette routine initialise le CIA a la frequence desiree */
  267. /**********************************************************/
  268.  
  269. int SetCIAInt()
  270. {
  271.     int code_ret;
  272.  
  273.     if( (GfxBase->DisplayFlags & PAL) !=0){
  274.         sprintf(RequIText8.IText,"PAL");
  275.         frequ=FREQU_PAL;
  276.     }else if( (GfxBase->DisplayFlags & NTSC) !=0){
  277.         sprintf(RequIText8.IText,"NTSC");
  278.         frequ=FREQU_NTSC;
  279.     }    
  280.     myCiaPointer=(struct Library *)OpenResource("ciab.resource");
  281.     if(myCiaPointer==NULL){
  282.         printf("Erreur ouverture ciab!\n");
  283.         code_ret=FALSE;
  284.     }else{
  285.         code_ret=TRUE;;
  286.     }
  287.     return(code_ret);
  288. }
  289.  
  290. /*******************************************************/
  291. /* Affiche une fenetre et attemd que lon clique dessus */
  292. /* et affiche aussi le texte intuition passe en param  */
  293. /*******************************************************/
  294.  
  295. void   show_window(p_newwindow,p_IText)
  296. struct NewWindow *p_newwindow;
  297. struct IntuiText *p_IText;
  298. {    
  299.     struct Window *p_wG;
  300.  
  301.     NewWindowStructure1.LeftEdge=wG->LeftEdge;
  302.     NewWindowStructure1.TopEdge=wG->TopEdge;
  303.     CloseWindow(wG);
  304.     if( (p_wG = OpenWindow(p_newwindow)) !=0){
  305.         if(p_IText!=NULL){
  306.             PrintIText(p_wG->RPort,p_IText,0,0);
  307.         }
  308.         WaitPort(p_wG->UserPort);
  309.         p_newwindow->LeftEdge=p_wG->LeftEdge;
  310.         p_newwindow->TopEdge =p_wG->TopEdge;
  311.         CloseWindow(p_wG);
  312.     }else{
  313.         printf("Ouverture deuxieme fenetre NOK!\n");
  314.     }
  315.     wG = OpenWindow(&NewWindowStructure1);    /* open the window */
  316.     if ( wG == NULL )
  317.     {
  318.         printf ("open window2 failed GROSSE ERREUR!\n");
  319.         exit(0);
  320.     }
  321. }
  322. /* This is for the event handler */
  323. void info(object)
  324. APTR object;
  325. {
  326.     show_window(&RequNewWindowStructure1,&RequIText2);
  327. }
  328.  
  329. /* This is for the event handler */
  330. void ico(object)
  331. APTR object;
  332. {
  333.     show_window(&IcoWindow,NULL);
  334. }
  335.  
  336. /*********************************************/
  337. /* Test un fichier contient un type de module*/
  338. /* que l'on connait.                 */
  339. /*********************************************/
  340.  
  341. int tst_file_type(p_filename,p_num_routine)
  342. char *p_filename;
  343. int  *p_num_routine;
  344. {
  345.    int code_ret;
  346.    char    *p_module;
  347.    struct FileLock *my_lock;
  348.  
  349.    code_ret=UNDEF;
  350.    if( (my_lock = (struct FileLock *)Open (p_filename, MODE_OLDFILE))==NULL){
  351.     printf("Ouverture NOK....Erreur!\n");
  352.    }else{
  353.     p_module=(char *)malloc(SIZE_INFO);
  354.         if( Read(my_lock,(char *)p_module,SIZE_INFO) == SIZE_INFO){
  355.         code_ret=tst_type(p_module,p_num_routine);
  356.     }
  357.     Close(my_lock);
  358.     free(p_module);
  359.    }
  360.  
  361.    return(code_ret);
  362. }
  363.  
  364. /************************************************************************/
  365. /* Cette routine teste le type du module, et retourne le type de module */
  366. /* si on le connait, UNDEF sinon                         */
  367. /************************************************************************/
  368.  
  369. tst_type(p_module,p_num_routine)
  370. char    *p_module;
  371. int  *p_num_routine;
  372. {
  373.     int code_ret;
  374.     char *tempo_p,*p_pattern;
  375.     int i,n;
  376.     code_ret=UNDEF;
  377.     i=0;
  378.         do{
  379.          p_pattern=tab_replay[i].p_ident;
  380.              tempo_p=p_module+tab_replay[i].offset;
  381.              n=0;
  382.              while( (p_pattern[n] == tempo_p[n]) && (p_pattern[n+1]!=0)){
  383.         n++;
  384.         if( p_pattern[n+1]=='/'){
  385.             *p_pattern++;
  386.         }
  387.          }
  388.  
  389.             if( p_pattern[n+1]==0){
  390. #ifdef DEBUG
  391.         printf("Replay found:%s\n",tab_replay[i].p_name);
  392. #endif
  393.                 code_ret=tab_replay[i].type_replay;
  394.         *p_num_routine=i;
  395.              }
  396.          i++;
  397.     }while((tab_replay[i].type_replay!=UNDEF) && (code_ret==UNDEF));
  398.     return(code_ret);
  399. }
  400.  
  401. /**********************************************************/
  402. /* This is the input event handler. I use special keyword */
  403. /* of the Lattice compiler. If you doesn't have these,you */
  404. /* must write it in ASM!                  */
  405. /**********************************************************/
  406.  
  407. struct InputEvent * __saveds __asm myproc_Handler
  408.             (reg __a0 struct InputEvent *ev,reg __a1 struct my_data *info)
  409. {
  410.     struct InputEvent *inev;
  411.  
  412.     inev = ev;
  413.     while (ev) {
  414.         if( (ev->ie_Qualifier &(IEQUALIFIER_LEFTBUTTON + IEQUALIFIER_RBUTTON ))==
  415.             ( IEQUALIFIER_LEFTBUTTON + IEQUALIFIER_RBUTTON )){
  416.                 Signal(info->task,1<<info->sigbit);
  417.             }
  418.         ev = ev->ie_NextEvent;
  419.     }
  420.     return (inev);
  421. }
  422.  
  423. /********************************************************/
  424. /* This is the initialisation of my input event handler */
  425. /********************************************************/
  426.  
  427. int    init_input_ev()
  428. {
  429.     my_info.sigbit=AllocSignal(-1);
  430.     if(my_info.sigbit==-1){
  431.         return(NOK);
  432.     }
  433.     my_info.task=(struct Task *)FindTask(0);
  434.  
  435.     if ( (inputreq = (struct IOStdreq *)CreateStdIO (port)) ==NULL){
  436.         return(NOK);
  437.     }
  438.     inputopen = OpenDevice ("input.device", 0L, inputreq, 0L);
  439.     if ( inputopen !=0 ){
  440.         return(NOK);
  441.     }
  442.  
  443.     myhandler.is_Code = (void (*)())myproc_Handler;
  444.     myhandler.is_Data =(APTR)&my_info;
  445.     myhandler.is_Node.ln_Pri = 51;
  446.     inputreq->io_Command = IND_ADDHANDLER;
  447.     inputreq->io_Data =(APTR) &myhandler;
  448.     DoIO (inputreq);
  449.  
  450.     return(OK);
  451. }
  452.  
  453. /******************************************************************/
  454. /* This is the liberation of the previously allocated ressources  */
  455. /* of the input event                          */
  456. /******************************************************************/
  457.  
  458. void    free_input_ev()
  459. {
  460.     if(inputreq){
  461.         inputreq->io_Command = IND_REMHANDLER;
  462.         inputreq->io_Data = (APTR)&myhandler;
  463.         DoIO (inputreq);
  464.     }
  465.     if (!inputopen) CloseDevice (inputreq);
  466.     if(inputreq)DeleteStdIO (inputreq);
  467.     if(my_info.sigbit!=-1)FreeSignal(my_info.sigbit);
  468.  
  469. int FileRequest()
  470.     {
  471.  
  472.     answerarray[0] = 0;
  473.  
  474.         /* Initialize the 'PathName' field so that the file requester will */
  475.         /* construct a complete path name for me.  It will also put the two */
  476.         /* parts of the answer (directory and file name) into the directory */
  477.         /* file name which I also decided to supply it with.  Since the */
  478.         /* directory and file name arrays are present, it will use their */
  479.         /* initial contents as the initial file and directory.  If they aren't */
  480.         /* present it will leave both blank to start. */
  481.     MyFileReqStruct.PathName = answerarray;
  482.     MyFileReqStruct.Dir = directoryname;
  483.     MyFileReqStruct.File = fname;
  484.  
  485.         /* The directory caching of this file requester is one of its nice */
  486.         /* features, so I decided to show it off.  It is completely optional */
  487.         /* though, so if you don't want it, don't set this flag.  If you do */
  488.         /* want it, don't forget to call PurgeFiles() when you are done. */
  489.     MyFileReqStruct.Flags = FRQCACHINGM;
  490.  
  491.         /* Initialize a few colour fields.  Not strictly necessary, but */
  492.         /* personally, I like having my files a different colour from my */
  493.         /* directories. */
  494.     MyFileReqStruct.dirnamescolor = 2;
  495.     MyFileReqStruct.devicenamescolor = 2;
  496.         /* I could also make it larger, pass it a file and/or directory */
  497.         /* name, set the window title, set various flags and customize */
  498.         /* in many other ways, but I wanted to show that it can be easily */
  499.         /* used without having to fill in a lot of fields. */
  500.     if (FileRequester(&MyFileReqStruct)){
  501.         return(1);
  502.     }else{
  503.         return(0);
  504.     }
  505. }
  506.  
  507. /***********************/
  508. /* PROGRAMME PRINCIPAL */
  509. /***********************/
  510.  
  511. main(argc,argv)
  512. int   argc;
  513. char  **argv;
  514.  
  515. {
  516.    struct  MsgPort *port_find;
  517.    int     sig_recu;
  518.  
  519.    struct WBArg *arg;
  520.    LONG   olddir;
  521.    int    i;
  522.  
  523.    ReqBase = (struct ReqBase *)OpenLibrary("req.library", 0L);
  524.    if(ReqBase==NULL){
  525.     printf("Shit, I Can't open req.library!\n");
  526.     goto cleanup1;
  527.    }
  528.    IntuitionBase = OpenLibrary("intuition.library", 0);
  529.    if (IntuitionBase == NULL)
  530.    {
  531.     printf("intuition is not here.  where are we?\n");
  532.     goto cleanup1;
  533.    }
  534.    GfxBase =(struct GfxBase *)OpenLibrary("graphics.library", 0);
  535.    if (GfxBase == NULL)
  536.    {
  537.     printf("gfx is not here.  where are we?\n");
  538.     goto cleanup1;
  539.    }
  540.  
  541.    /* If the port is already existing, we send a signal to tell the */
  542.    /* active multi_player to stop. If it stop, it remove the port   */
  543.    /* If after sending the signal, the port is still here, this mean*/
  544.    /* that the other nulti_player was running with a window, so you */
  545.    /* can't stop like this                                          */
  546.  
  547.    if( (port_find=FindPort (portname)) !=NULL){
  548.     Signal(port_find->mp_SigTask,1<<port_find->mp_SigBit);
  549.     Delay(2);
  550.    }
  551.    if( FindPort (portname) !=NULL){
  552.     SimpleRequest("Sorry, there is another multi_player running");
  553.     goto cleanup1;
  554.    }else if((port=(struct MsgPort *)CreatePort (portname, 0L)) ==NULL){
  555.     goto cleanup1;
  556.    }
  557.    if(SetCIAInt() == FALSE){
  558.     goto cleanup1;
  559.    }
  560.    /********************************************************************/
  561.    /* If the programm have an argument, we assume that's a module name */
  562.    /********************************************************************/
  563.  
  564.    if( (argc>1) || ( (WBenchMsg->sm_NumArgs>1)&&(argc==0)) ){
  565.     sig_recu=0;
  566.     if(init_input_ev()==OK){
  567.  
  568.         /* There is on signal waiting, so we remove it */
  569.         Wait(1<<port->mp_SigBit);
  570.  
  571.         if(argc>1){
  572.             /***********************/
  573.             /* It was run from CLI */
  574.             /***********************/
  575.  
  576.             for(    i=1;
  577.                 (i<argc) && (sig_recu != 1<<port->mp_SigBit);
  578.                 i++
  579.             ){
  580. #ifdef DEBUG
  581.                 printf("argv:%s\n",argv[i]);
  582. #endif
  583.                 play_module(argv[i],&my_interrupt);
  584.                 if(type_replay!=UNDEF){
  585.                     sig_recu=Wait((1<<my_info.sigbit) | (1<<port->mp_SigBit));
  586.                  }
  587.             }
  588.         }else{
  589.             /***********************/
  590.             /* It was run from WB  */
  591.             /***********************/
  592.  
  593.                 for(    i=1,arg=WBenchMsg->sm_ArgList,arg++;
  594.                 (i<WBenchMsg->sm_NumArgs) && (sig_recu!=1<<port->mp_SigBit);
  595.                 i++,arg++
  596.             ){
  597.  
  598.                 olddir=CurrentDir(arg->wa_Lock);
  599.                 play_module(arg->wa_Name,&my_interrupt);
  600.                 if(type_replay!=UNDEF){
  601.                     sig_recu=Wait((1<<my_info.sigbit) | (1<<port->mp_SigBit));
  602.                 }
  603.                 CurrentDir(olddir);
  604.             }
  605.         }
  606.     }
  607.     free_input_ev();
  608.    }else{
  609.  
  610.     /********************************************************/
  611.     /* The programm is run with no argument, so we open the */
  612.     /* window and ask for a file to load!            */
  613.     /********************************************************/
  614.  
  615.     wG = OpenWindow(&NewWindowStructure1);    /* open the window */
  616.     if ( wG == NULL )
  617.     {
  618.         printf ("open window failed\n");
  619.         goto cleanup1;
  620.     }else{
  621.  
  622.        do{
  623.  
  624.             /***************************************************/
  625.         /* We ask the user for a file to load. If he gives */
  626.         /* one, we try to load it and to play it       */
  627.             /***************************************************/
  628.  
  629.         if(FileRequest() !=0 ){
  630.             play_module(answerarray,&my_interrupt);
  631.     
  632.         }
  633.         main_loop(num_replay);
  634.  
  635.        }while(quit_flag == FALSE);
  636.     }
  637.     }
  638.  
  639. cleanup2:
  640.    if ( wG != NULL) CloseWindow(wG);
  641. cleanup1:
  642.    stop(&my_interrupt);
  643.    if(type_replay!=UNDEF){
  644.        exec_safe(tab_replay[num_replay].p_end);
  645.    }
  646.  
  647.    /**************************************************/
  648.    /* If memory was previously allocated, we free it */
  649.    /**************************************************/
  650.  
  651.    My_FreeMem(&adr_data,size_file);
  652.    My_FreeMem(&adr_data2,size_file2);
  653.  
  654.    if (port) DeletePort (port);
  655.  
  656.    if (ReqBase != NULL)   CloseLibrary(ReqBase);
  657.    if (GfxBase != NULL)   CloseLibrary(GfxBase);
  658.    if (IntuitionBase != NULL) CloseLibrary(IntuitionBase);
  659.    return(0);
  660.  
  661. }
  662.  
  663. /**************************************************************/
  664. /* This function load a module and activate the interrupt     */
  665. /* handler with the correct replayroutine                     */
  666. /**************************************************************/
  667. /* p_name=pointer to the filename                             */
  668. /* pp_interrupt=pointer to the var containing the interrupt struct */
  669.  
  670. int play_module(p_name,pp_interrupt)
  671. char *p_name;
  672. struct   Interrupt **pp_interrupt;
  673. {
  674.        int err;
  675.  
  676.     if(type_replay!=UNDEF){
  677.         old_end=tab_replay[num_replay].p_end;
  678.     }
  679.     type_replay=tst_file_type(p_name,&num_replay);
  680.  
  681.         /************************************************/
  682.     /* Si il y a un fichier de charge, on l'execute */
  683.         /************************************************/
  684.  
  685.     if(type_replay!=UNDEF){
  686.  
  687.         /*****************************************************/
  688.         /* Si l'on etait en train de jouer qq chose, on stop */
  689.         /*****************************************************/
  690.  
  691.         if(old_end!=NULL){
  692.         exec_safe(old_end);
  693.         }
  694.  
  695.         stop(pp_interrupt);
  696.  
  697.  
  698.         /***************************************/
  699.         /* Si c'est du powerpacker, on charge! */
  700.         /***************************************/
  701.         My_FreeMem(&adr_data,size_file);
  702.            
  703.         err = PP_LoadData (p_name, DECR_POINTER,
  704.                         MEMF_PUBLIC+MEMF_CHIP, &adr_data, &size_file, NULL); 
  705.         if (err == PP_LOADOK) {                                      
  706.                 if(type_replay==PP){
  707.             type_replay=tst_type(adr_data,&num_replay);
  708.             }                                                         
  709.         }else{
  710.         if(err==PP_LOCKERR){
  711.             SimpleRequest("File:%s not found!",p_name);
  712.         }
  713.         My_FreeMem(&adr_data,size_file);
  714.         }
  715.  
  716.         /********************************************************/
  717.         /* Si tout est bien charge,  et si le replay est defini,*/
  718.         /* et bien on execute le programme!!!                   */
  719.         /********************************************************/
  720.  
  721.         if((adr_data!=NULL) && (type_replay !=UNDEF) ){
  722.         My_FreeMem(&adr_data2,size_file2);
  723.  
  724.         /**********************************************************/
  725.         /* Si c'est un modules startrekker AM, on charge la suite */
  726.         /**********************************************************/
  727.  
  728.         if( (type_replay == STARTREKKER)||(type_replay == NOISETRACKER)){
  729.             read_file_nt(p_name);
  730. /*
  731.             if(adr_data2==0){
  732.                My_FreeMem(&adr_data,size_file);
  733.                type_replay=UNDEF;
  734.             }
  735. */
  736.         }
  737.         if(type_replay == TFMX){
  738.             read_file_tfmx(p_name);
  739.             if(adr_data2==0){
  740.                My_FreeMem(&adr_data,size_file);
  741.                type_replay=UNDEF;
  742.             }
  743.         }
  744.         if(wG!=NULL)SetWindowTitles(wG,fname,fname);
  745.         sprintf(RequIText4.IText,"Module Name:%.26s",fname);
  746.         if(adr_data2!=0){
  747.             sprintf(RequIText5.IText,"Module Size:%d+%d",size_file,size_file2);
  748.         }else{
  749.             sprintf(RequIText5.IText,"Module Size:%d",size_file);
  750.         }
  751.         sprintf(RequIText6.IText,"Replay Used:%.22s",tab_replay[num_replay].p_name);
  752.  
  753.  
  754.         exec_safe(tab_replay[num_replay].p_start);
  755.         if(setup(pp_interrupt,tab_replay[num_replay].p_music)!=OK){
  756.             num_replay=UNDEF;
  757.         }
  758.   
  759.        }
  760.     }else{
  761.         SimpleRequest("Unknow replay!");
  762.     }
  763.     return(num_replay);
  764. }
  765.  
  766. /**********************************************/
  767. /* Procedure d'attente d'evenements intuition */
  768. /**********************************************/
  769.  
  770. void main_loop(num_replay)
  771. int num_replay;
  772. {
  773.     struct IntuiMessage *message;    /* the message the IDCMP sends us */
  774.     UWORD code;
  775.     ULONG class;
  776.     APTR object;
  777.  
  778.     flag_out=FALSE;
  779.     do
  780.     {
  781.         WaitPort(wG->UserPort);
  782.  
  783.         while( (message = (struct IntuiMessage *)
  784.             GetMsg(wG->UserPort) ) != NULL)
  785.             {
  786.                 code = message->Code;  /* MENUNUM */
  787.                 object = message->IAddress;  /* Gadget */
  788.                 class = message->Class;
  789.                 ReplyMsg(message);
  790.                 switch(class){
  791.                      case  CLOSEWINDOW:
  792.                      flag_out = TRUE;
  793.                      quit_flag= TRUE;
  794.                       break;
  795.                      case  GADGETUP:
  796.                      case  GADGETDOWN:
  797.                     HandleEvent(object);
  798.                     break;
  799.                      case VANILLAKEY:
  800.  
  801.                     if( (code>='0') && (code<='9')) {
  802.                         num_musique=code-'1';
  803.                         if(code==-1)code=10;
  804.  
  805.                         if( (tab_replay[num_replay].type_replay==FRED)||
  806.                             (tab_replay[num_replay].type_replay==TFMX)){
  807.                             exec_safe(tab_replay[num_replay].p_start);
  808.                         }
  809.                     }
  810.                     break;
  811.                      default:
  812.                     break;
  813.                 }
  814.  
  815.             }
  816.     } while (flag_out == FALSE);
  817. }
  818.  
  819.  
  820. /*************************************************/
  821. /* Lecture d'un fichier de sons de noisetrakcer! */
  822. /*************************************************/
  823.  
  824. void read_file_nt(p_filename)
  825. char *p_filename;
  826. {
  827.    char  *buffer;
  828.    int err;
  829.    /* Lecture du deuxieme fichier! */
  830.  
  831.    buffer=(char *)malloc(strlen(p_filename)+5);
  832.    sprintf(buffer,"%s.NT",p_filename);
  833.  
  834.     err = PP_LoadData (buffer, DECR_POINTER,
  835.                            MEMF_PUBLIC+MEMF_CHIP, &adr_data2, &size_file2, NULL); 
  836.     if (err != PP_LOADOK) {                                      
  837.     My_FreeMem(&adr_data2,size_file2);
  838. /*
  839.     if(err==PP_LOCKERR){
  840.         SimpleRequest("File:%s not found!",buffer);
  841.     }
  842. */
  843.     }
  844.     free(buffer);
  845. }
  846. /*****************************************/
  847. /* Load a TFMX smpl data file!           */
  848. /*****************************************/
  849.  
  850. void read_file_tfmx(p_filename)
  851. char *p_filename;
  852. {
  853.    char  *buffer;
  854.    int err,i;
  855.    /* Lecture du deuxieme fichier! */
  856.    buffer=(char *)malloc(strlen(p_filename)+1);
  857.    strcpy(buffer,p_filename);
  858.    i=0;
  859.    while( (buffer[i]!='m') || (buffer[i+1] != 'd') || (buffer[i+2] != 'a') || (buffer[i+3] != 't')){
  860.     i++;
  861.    }
  862.    buffer[i]='s';
  863.    buffer[i+1]='m';
  864.    buffer[i+2]='p';
  865.    buffer[i+3]='l';
  866.  
  867.     err = PP_LoadData (buffer, DECR_POINTER,
  868.                            MEMF_PUBLIC+MEMF_CHIP, &adr_data2, &size_file2, NULL); 
  869.     if (err != PP_LOADOK) {
  870.     My_FreeMem(&adr_data2,size_file2);
  871.     if(err==PP_LOCKERR){
  872.         SimpleRequest("File:%s not found!",buffer);
  873.     }
  874.     }
  875.     free(buffer);
  876. }
  877.  
  878. /**************************************************/
  879. /* Initialisation de notre handler d'interruption */
  880. /**************************************************/
  881.  
  882. int    setup(pp_interrupt,p_func)
  883. struct    Interrupt **pp_interrupt;
  884. void    (*p_func)();
  885. {
  886.  
  887.    if(*pp_interrupt!=NULL){
  888.     printf("Erreur,pp_interrupt <>0! Deja alloue?\n");
  889.     return(NOK);
  890.    }
  891.    *pp_interrupt=(struct Interrupt *)My_AllocMem(sizeof(struct Interrupt),
  892.                                                 MEMF_PUBLIC,pp_interrupt);
  893.  
  894.    if(*pp_interrupt == NULL){
  895.     printf("Pas assez de memoire pour la structure d'interruption\n");
  896.     return(NOK);
  897.    }
  898.    (*pp_interrupt)->is_Node.ln_Type=NT_INTERRUPT;
  899.    (*pp_interrupt)->is_Node.ln_Pri=0;
  900.    (*pp_interrupt)->is_Node.ln_Name="Multi replay Interrupt";
  901.    (*pp_interrupt)->is_Data=(APTR)p_func;
  902.    (*pp_interrupt)->is_Code=interrupt_music;
  903.  
  904.    if(AddICRVector(myCiaPointer,CIAICRB_TA,*pp_interrupt)!=0){
  905.     SimpleRequest("I can't allocate the interruption");
  906.     return(NOK);
  907.    }else{
  908.     ciab.ciatalo=(UBYTE)(frequ & 0xff);
  909.     ciab.ciatahi=(UBYTE)((frequ>>8) & 0xff);
  910.     ciab.ciacra|=1;
  911.    }
  912.    return(OK);
  913. }
  914.  
  915. /******************************************/
  916. /* Arret  de notre handler d'interruption */
  917. /******************************************/
  918.  
  919. void stop(pp_interrupt)
  920. struct Interrupt **pp_interrupt;
  921. {
  922.    if(*pp_interrupt != NULL){
  923.     AbleICR(myCiaPointer,(1<<CIAICRB_TA) );
  924.        RemICRVector(myCiaPointer,CIAICRB_TA,*pp_interrupt);
  925.     My_FreeMem(pp_interrupt,sizeof(struct Interrupt));
  926.         *pp_interrupt=NULL;
  927.    }
  928. }
  929.  
  930.